
// 试一试input子系统和tslib
// 设备的初始化
// 上报的报文的处理(比如是不是按下了之类的)
// 此时两个 主机 和 开发板 要使用同一个tslib库
// input这里处理数据 然后把有效数据报给lcd线程就行
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <tslib.h>
#include "input.h"
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/msg.h>
// msg_key : 消息队列的key值
// 这个触摸就很怪，我的线好像烧了咋了出不来了 就先不测试了
void* input_init(void * arg)
{
    const int msg_key = *(int *)arg; 

    struct tsdev *ts = NULL;
    struct ts_sample_mt *mt_ptr = NULL;
    struct input_absinfo slot;
    int max_slots;
    unsigned int pressure[12] = {0};   //用于保存每一个触摸点上一次的按压力,初始为0,表示松开
    int i;

    /* 打开并配置触摸屏设备 */
    ts = ts_setup(NULL, 0);
    if (NULL == ts) {
        fprintf(stderr, "ts_setup error");
        pthread_exit(NULL);
    }

    /* 获取触摸屏支持的最大触摸点数 */
    if (0 > ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot)) {
        perror("ioctl error");
        ts_close(ts);
        pthread_exit(NULL);
    }

    max_slots = slot.maximum + 1 - slot.minimum;
    printf("max_slots: %d\n", max_slots);

    /* 内存分配 */
    mt_ptr = calloc(max_slots, sizeof(struct ts_sample_mt));

        /* 读数据 */
    for ( ; ; ) {
        if (0 > ts_read_mt(ts, &mt_ptr, max_slots, 1)) {
            perror("ts_read_mt error");
            ts_close(ts);
            free(mt_ptr);
            pthread_exit(NULL);
        }
        for (i = 0; i < max_slots; i++) {
            if (mt_ptr[i].valid) {//有效表示有更新!
                if (mt_ptr[i].pressure) { //如果按压力>0
                    if (pressure[mt_ptr[i].slot]) {//如果上一次的按压力>0 {
                        if(mt_ptr[i].y > BUTTON_START_Y) {
                            struct msg touch_msg;
                            switch(mt_ptr[i].x / 200) {
                                case 0:         // 开始/暂停Carama的捕捉
                                    touch_msg.type = CARAMA_MSG_TYPE;
                                    touch_msg.detail_msg.carama_msg = CARAMA_STATE_CHANGE;
                                    if (msgsnd(msg_key, &touch_msg, sizeof(touch_msg.detail_msg), 0) == -1) {
                                        perror("msgsnd error : CARAMA_STATE_CHANGE");
                                    }
                                    printf("CARAMA_STATE_CHANGE successful\r\n");
                                    break;
                                case 1:
                                    touch_msg.type = CARAMA_MSG_TYPE;
                                    touch_msg.detail_msg.carama_msg = CARAMA_FROMAT_CHANGE;
                                    if (msgsnd(msg_key, &touch_msg, sizeof(touch_msg.detail_msg), 0) == -1) {
                                        perror("msgsnd error : CARAMA_FROMAT_CHANGE");
                                    }
                                    printf("CARAMA_FROMAT_CHANGE successful\r\n");
                                    break;
                                case 2:       
                                    touch_msg.type = LED_MSG_TYPE;
                                    touch_msg.detail_msg.led_msg = LED0_STATE_CHANGE;
                                    if (msgsnd(msg_key, &touch_msg, sizeof(touch_msg.detail_msg), 0) == -1) {
                                        perror("msgsnd error : LED0_STATE_CHANGE");
                                    }
                                    printf("CARAMA_FROMAT_CHANGE successful\r\n");
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                } // 有点幽默了这括号镶嵌哈哈
                pressure[mt_ptr[i].slot] = mt_ptr[i].pressure;
            }
        }
    }
    
    /* 关闭设备、释放内存、退出 */
    ts_close(ts);
    free(mt_ptr);
    pthread_exit(NULL);
}
int main()
{
    // 创建消息队列
    int msg_key = msgget(12345, IPC_CREAT | 0666);
    if (msg_key == -1) {
        perror("msgget error");
        return -1;
    }
    // 放入lcd的CacheBuffer中
    pthread_t ts_tid;
    if (pthread_create(&ts_tid, NULL, input_init, &msg_key) != 0) {
        perror("pthread_create error");
        msgctl(msg_key, IPC_RMID, NULL); // 删除消息队列
        return -1;
    }
    //等待线程结束
    pthread_join(ts_tid, NULL);
    // 删除消息队列
    msgctl(msg_key, IPC_RMID, NULL);
    // 释放资源
    return 0;
}
